package com.bite.ojcommonsecurity.handler;


import cn.hutool.core.util.StrUtil;
import com.bite.ojcommoncore.domain.result.R;
import com.bite.ojcommoncore.enums.ResultCode;
import com.bite.ojcommonsecurity.exception.BaseException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.sql.SQLIntegrityConstraintViolationException;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
import cn.hutool.core.collection.CollUtil;
import org.springframework.context.support.DefaultMessageSourceResolvable;
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {


    @ExceptionHandler
    public R<Object> handleException(Exception ex) {
        log.error("全局异常 * {} * {} * ",ex.getClass(),ex.getMessage());
        return R.fail(ResultCode.ERROR.getCode(),ResultCode.ERROR.getMsg());
    }


//    @ExceptionHandler
//    public R<Object> handleException(BaseException ex) {
//        log.error("异常信息 * {} * {} * ",ex.getClass(),ex.getMessage());
//        return R.fail(ResultCode.ERROR.getCode(),ResultCode.ERROR.getMsg());
//    }


    /**
     * 获取员工存在重复添加的sql异常
     * @param exception
     * @return
     */
    @ExceptionHandler
    public R<Object> exceptionHandler(SQLIntegrityConstraintViolationException exception) {
        log.error("异常信息 * {} * {} * ",exception.getClass(),exception.getMessage());
        String message = exception.getMessage();
        if (message.contains("Duplicate entry")) {
            String[] split = message.split(" ");
            String name = split[2];
            return R.fail(ResultCode.AILED_USER_EXISTS.getCode(),name + ResultCode.AILED_USER_EXISTS.getMsg());
        }
        return R.fail(ResultCode.ERROR.getCode(),ResultCode.ERROR.getMsg());
    }

    /**
     * 用户账号重复添加的sql异常
     * @param exception
     * @return
     */
    @ExceptionHandler
    public R<Object> exceptionHandler(DuplicateKeyException exception) {
        log.error("唯一值重复异常 {} * {} * ",exception.getClass(),exception.getMessage());
        String message = exception.getMessage();
        if (message.contains("Duplicate entry")) {
            String[] split = message.split(" ");
            String name = split[9];
            return R.fail(ResultCode.AILED_USER_EXISTS.getCode(),name + ResultCode.AILED_USER_EXISTS.getMsg());
        }
        return R.fail(ResultCode.ERROR.getCode(),ResultCode.ERROR.getMsg());
    }


//    @ExceptionHandler(BindException.class)
//    public R<Object> exceptionHandler(BindException exception) {
//        log.error("参数校验异常  {} * {} * ",exception.getClass(),exception.getMessage());
//        String message = exception.getMessage();
//        if (message.contains("Duplicate entry")) {
//            String[] split = message.split(" ");
//            String name = split[split.length-1];
//            return R.fail(ResultCode.AILED_USER_EXISTS.getCode(),name + ResultCode.AILED_USER_EXISTS.getMsg());
//        }
//        return R.fail(ResultCode.ERROR.getCode(),ResultCode.ERROR.getMsg());
//    }

    /**
     * 后端参数校验异常捕获
     * @param e
     * @return
     */
    @ExceptionHandler(BindException.class)
    public R<Void> handleBindException(BindException e) {
        log.error(e.getMessage());
//        log.error("##########");
//        log.error("{}" ,e.getAllErrors());

        List<String> collect = e.getAllErrors()
                .stream()
                .map(DefaultMessageSourceResolvable::getDefaultMessage)
                .collect(Collectors.toList());

        String message = join(e.getAllErrors(),
                DefaultMessageSourceResolvable::getDefaultMessage, ", ");
//        List<ObjectError> errors = e.getBindingResult().getGlobalErrors();
        //        for (ObjectError error : errors) {
//            log.error("global error: {} \n", error.getDefaultMessage());
//        }
        List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
        StringBuilder stringBuilder = new StringBuilder();
        for (FieldError fieldError : fieldErrors) {

            stringBuilder.append(fieldError.getDefaultMessage() + ",");
        }
        return R.fail(ResultCode.FAILED_PARAMS_VALIDATE.getCode(), stringBuilder.toString());
    }

    private <E> String join(Collection<E> collection, Function<E, String>
            function, CharSequence delimiter) {
        if(CollUtil.isEmpty(collection)) {
            return StrUtil.EMPTY;
        }
        return collection.stream().map(function).filter(Objects::nonNull).collect(Collectors.joining(delimiter));
    }

    @ExceptionHandler(BaseException.class)
    public R<Void> handleBaseException(BaseException e) {
        log.error(e.getMessage());
        return R.fail(ResultCode.ERROR.getCode(),e.getMessage());
    }
}
